package platform

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"strconv"
	"time"

	"gitee.com/wangshh_123/cross-pay-go/src/errors"
	"gitee.com/wangshh_123/cross-pay-go/src/middleware"
	"gitee.com/wangshh_123/cross-pay-go/src/models"
	platformCommon "gitee.com/wangshh_123/cross-pay-go/src/platform/common"
	"gitee.com/wangshh_123/cross-pay-go/src/platform/integration"
	hlpayModels "gitee.com/wangshh_123/cross-pay-go/src/platform/providers/hlPay/models"
	"gitee.com/wangshh_123/cross-pay-go/src/service"
	"gitee.com/wangshh_123/cross-pay-go/src/utils/common"

	"github.com/gin-gonic/gin"
	"github.com/shopspring/decimal"
)

// OpenCard 统一开卡接口
// 以PhotonPay的参数格式作为模板，自动适配不同平台
func (c *UnifiedCardController) OpenCard(ctx *gin.Context) {
	// 从中间件获取平台信息
	platformInfo, exists := middleware.GetPlatformInfoFromContext(ctx)
	if !exists {
		common.Error(ctx, http.StatusUnauthorized, "platform_info_not_found", nil)
		return
	}

	// 添加调试信息
	fmt.Printf("[OpenCard] 平台信息: %+v\n", platformInfo)

	// 获取矩阵账户信息
	matrixInfo, exists := ctx.Get("matrix_account_info")
	if !exists {
		common.Error(ctx, http.StatusUnauthorized, "matrix_account_not_found", nil)
		return
	}

	matrixAccountInfo, ok := matrixInfo.(*models.UserMatrixAccount)
	if !ok {
		common.Error(ctx, http.StatusInternalServerError, "matrix_account_invalid", nil)
		return
	}

	// 获取用户角色和余额信息
	userInfo, err := c.getUserRoleAndBalance(ctx)
	if err != nil {
		common.Error(ctx, err.(*errors.AppError).Code, err.Error(), nil)
		return
	}

	// 解析PhotonPay格式的请求参数（前端统一使用PhotonPay格式）
	var req struct {
		AccountId            string  `json:"accountId" binding:"omitempty"`
		AccountNo            string  `json:"accountNo" binding:"omitempty"` // HlPay账户号，如 "HL-USD1750844106122552900"
		Bin                  string  `json:"bin" binding:"omitempty"`       // 卡BIN号，如 "404038"
		CardBin              string  `json:"cardBin" binding:"omitempty"`   // 兼容PhotonPay格式的卡BIN号
		CardBinId            string  `json:"cardBinId" binding:"omitempty"` // 卡Bin ID，如 "1859844012441174018"
		CardholderId         string  `json:"cardholderId" binding:"required"`
		CardCurrency         string  `json:"cardCurrency" binding:"required"`
		CardExpirationDate   int     `json:"cardExpirationDate" binding:"required"`
		CardScheme           string  `json:"cardScheme" binding:"required"`
		CardType             string  `json:"cardType" binding:"required"`
		CardFormFactor       string  `json:"cardFormFactor" binding:"required"`
		RechargeAmount       string  `json:"rechargeAmount" binding:"omitempty"`
		Cost                 float64 `json:"cost" binding:"omitempty"` // HlPay的Cost字段，用于设置卡片初始金额
		RequestId            string  `json:"requestId" binding:"required"`
		TransactionLimitType string  `json:"transactionLimitType" binding:"omitempty"`
		Nickname             string  `json:"nickname"`
		CardCount            int     `json:"cardCount" binding:"omitempty,min=1,max=10"`
		TimeoutSeconds       int     `json:"timeoutSeconds" binding:"omitempty,min=5,max=60"`
		// HlPay特有字段（可选）
		CardAddress string `json:"cardAddress" binding:"omitempty"`
		BillAddress string `json:"billAddress" binding:"omitempty"`
		FirstName   string `json:"firstName" binding:"omitempty"`
		LastName    string `json:"lastName" binding:"omitempty"`
		Email       string `json:"email" binding:"omitempty"`
		Phone       string `json:"phone" binding:"omitempty"`
		City        string `json:"city" binding:"omitempty"`
		State       string `json:"state" binding:"omitempty"`
		Zip         string `json:"zip" binding:"omitempty"`
		BatchCount  string `json:"batchCount" binding:"omitempty"`
	}

	if err := ctx.ShouldBindJSON(&req); err != nil {
		common.Error(ctx, http.StatusBadRequest, "invalid_params", err)
		return
	}

	// 验证至少有一个BIN字段被提供
	if req.Bin == "" && req.CardBin == "" {
		common.Error(ctx, http.StatusBadRequest, "bin_required", fmt.Errorf("either 'bin' or 'cardBin' field is required"))
		return
	}

	// 验证cardholderId
	if req.CardholderId == "" || req.CardholderId == "undefined" {
		common.Error(ctx, http.StatusBadRequest, "invalid_cardholder_id", fmt.Errorf("cardholderId is required and cannot be 'undefined'"))
		return
	}

	// 设置默认开卡数量为1
	if req.CardCount <= 0 {
		req.CardCount = 1
	}

	// 设置默认超时时间为15秒
	if req.TimeoutSeconds <= 0 {
		req.TimeoutSeconds = 15
	}

	// 处理充值金额：优先使用cost字段，如果没有则使用rechargeAmount
	var rechargeAmountStr string
	var rechargeAmountFloat float64
	var hasRechargeAmount bool

	if req.Cost > 0 {
		// 优先使用cost字段
		rechargeAmountStr = fmt.Sprintf("%.2f", req.Cost)
		rechargeAmountFloat = req.Cost
		hasRechargeAmount = true
		fmt.Printf("[UnifiedCard] 使用Cost字段作为充值金额: %f\n", req.Cost)
	} else if req.RechargeAmount != "" {
		// 如果没有cost字段，使用rechargeAmount
		rechargeAmountStr = req.RechargeAmount
		if amount, err := strconv.ParseFloat(req.RechargeAmount, 64); err == nil {
			rechargeAmountFloat = amount
			hasRechargeAmount = true
		}
		fmt.Printf("[UnifiedCard] 使用RechargeAmount字段作为充值金额: %s\n", req.RechargeAmount)
	}

	// 临时日志：记录跳过余额检查
	if hasRechargeAmount && platformInfo.PlatformType == "hlpay" {
		fmt.Printf("[UnifiedCard] HlPay开卡暂时跳过余额检查（将通过webhook回调处理）: 金额=%f\n", rechargeAmountFloat)
	} else if hasRechargeAmount && platformInfo.PlatformType == "photonpay" {
		fmt.Printf("[UnifiedCard] PhotonPay平台跳过本地余额检查，由第三方平台处理余额验证\n")
	}

	// 构建统一的开卡请求
	// 优先使用bin字段，如果没有则使用cardBin字段
	cardBin := req.Bin
	if cardBin == "" {
		cardBin = req.CardBin
	}

	openCardRequest := &platformCommon.OpenCardRequest{
		UserID:               userInfo.UserID,
		MatrixAccount:        matrixAccountInfo.MatrixAccount,
		AccountID:            req.AccountId,
		AccountNo:            req.AccountNo,
		CardBin:              cardBin,
		CardBinId:            req.CardBinId,
		CardholderID:         req.CardholderId,
		CardCurrency:         req.CardCurrency,
		CardExpirationDate:   req.CardExpirationDate,
		CardScheme:           req.CardScheme,
		CardType:             req.CardType,
		CardFormFactor:       req.CardFormFactor,
		Cost:                 req.Cost,          // 直接传递Cost字段
		RechargeAmount:       rechargeAmountStr, // 使用处理后的充值金额
		RequestID:            req.RequestId,
		TransactionLimitType: req.TransactionLimitType,
	}

	// 添加调试信息
	fmt.Printf("[UnifiedCard] 构建开卡请求:\n")
	fmt.Printf("  - 原始Cost字段: %f\n", req.Cost)
	fmt.Printf("  - 原始RechargeAmount字段: %s\n", req.RechargeAmount)
	fmt.Printf("  - 处理后的rechargeAmountStr: %s\n", rechargeAmountStr)
	fmt.Printf("  - 最终Cost字段: %f\n", openCardRequest.Cost)
	fmt.Printf("  - 最终RechargeAmount字段: %s\n", openCardRequest.RechargeAmount)

	// HLPay 平台参数适配
	if platformInfo.PlatformType == "hlpay" {
		// 验证持卡人信息
		var cardholder hlpayModels.HlPayCardholder
		if err := c.db.Where("hlpay_cardholder_id = ?", req.CardholderId).First(&cardholder).Error; err != nil {
			common.Error(ctx, http.StatusBadRequest, "hlpay_cardholder_not_found", fmt.Errorf("持卡人不存在: %s", req.CardholderId))
			return
		}

		// 检查持卡人状态
		if cardholder.Status != "ACTIVE" {
			common.Error(ctx, http.StatusBadRequest, "hlpay_cardholder_inactive", fmt.Errorf("持卡人状态异常: %s", cardholder.Status))
			return
		}

		// 验证账户信息 - 优先使用AccountNo，如果没有则使用AccountId
		accountNo := req.AccountNo
		if accountNo == "" {
			accountNo = req.AccountId
		}

		var account models.HlPayAccountBalance
		if err := c.db.Where("account_no = ?", accountNo).First(&account).Error; err != nil {
			common.Error(ctx, http.StatusBadRequest, "hlpay_account_not_found", fmt.Errorf("账户不存在: %s", accountNo))
			return
		}

		// 检查账户状态
		if account.Status != "active" {
			common.Error(ctx, http.StatusBadRequest, "hlpay_account_inactive", fmt.Errorf("账户状态异常: %s", account.Status))
			return
		}

		// 设置HlPay特定的参数
		openCardRequest.AccountID = account.AccountNo
		openCardRequest.AccountNo = account.AccountNo
		openCardRequest.CardholderID = cardholder.HlPayCardholderID

		// 打印调试信息
		fmt.Printf("[HLPay] 开卡参数适配:\n")
		fmt.Printf("  - 持卡人ID: %s\n", cardholder.HlPayCardholderID)
		fmt.Printf("  - 持卡人姓名: %s %s\n", cardholder.FirstName, cardholder.LastName)
		fmt.Printf("  - 持卡人邮箱: %s\n", cardholder.Email)
		fmt.Printf("  - 持卡人手机: %s\n", cardholder.Mobile)
		fmt.Printf("  - 持卡人地址: %s, %s, %s %s\n", cardholder.ResidentialAddress, cardholder.ResidentialCity, cardholder.ResidentialState, cardholder.ResidentialPostalCode)
		fmt.Printf("  - 账户号: %s\n", account.AccountNo)
		fmt.Printf("  - 账户余额: %s\n", account.RealTimeBalance.String())
		fmt.Printf("  - 请求中的bin字段: %s\n", req.Bin)
		fmt.Printf("  - 请求中的cardBin字段: %s\n", req.CardBin)
		fmt.Printf("  - 最终使用的卡BIN: %s\n", cardBin)
		if req.Cost > 0 {
			fmt.Printf("  - Cost字段: %f\n", req.Cost)
		}
		if req.RechargeAmount != "" {
			fmt.Printf("  - RechargeAmount字段: %s\n", req.RechargeAmount)
		}
		if hasRechargeAmount {
			fmt.Printf("  - 最终充值金额: %s\n", rechargeAmountStr)
		}
		// 打印HlPay特有字段
		if req.CardAddress != "" {
			fmt.Printf("  - 卡片地址: %s\n", req.CardAddress)
		}
		if req.BillAddress != "" {
			fmt.Printf("  - 账单地址: %s\n", req.BillAddress)
		}
		if req.FirstName != "" {
			fmt.Printf("  - 请求中的名字: %s\n", req.FirstName)
		}
		if req.LastName != "" {
			fmt.Printf("  - 请求中的姓氏: %s\n", req.LastName)
		}
		if req.Email != "" {
			fmt.Printf("  - 请求中的邮箱: %s\n", req.Email)
		}
		if req.Phone != "" {
			fmt.Printf("  - 请求中的电话: %s\n", req.Phone)
		}
		if req.City != "" {
			fmt.Printf("  - 请求中的城市: %s\n", req.City)
		}
		if req.State != "" {
			fmt.Printf("  - 请求中的州: %s\n", req.State)
		}
		if req.Zip != "" {
			fmt.Printf("  - 请求中的邮编: %s\n", req.Zip)
		}
		if req.BatchCount != "" {
			fmt.Printf("  - 批量数量: %s\n", req.BatchCount)
		}
	}

	// 添加调试信息
	fmt.Printf("[OpenCard] 平台类型: %s\n", platformInfo.PlatformType)
	fmt.Printf("[OpenCard] 开卡请求: %+v\n", openCardRequest)

	// 检查平台管理器是否支持该平台
	supportedPlatforms := c.platformManager.GetFactory().GetSupportedPlatforms()
	fmt.Printf("[OpenCard] 支持的平台: %v\n", supportedPlatforms)

	// HlPay平台开卡前插入pending记录
	var openRecordID int64 = 0
	if platformInfo.PlatformType == "hlpay" {
		record := models.HlpayCardOpenRecord{
			UserID:            userInfo.UserID,
			MatrixAccount:     matrixAccountInfo.MatrixAccount,
			Platform:          platformInfo.PlatformType,
			CardID:            "", // 未知
			CardScheme:        req.CardScheme,
			CardType:          req.CardType,
			CardFormFactor:    req.CardFormFactor,
			MaskCardNo:        "",
			MemberID:          "",
			Nickname:          req.Nickname,
			CardNickname:      req.Nickname,
			ReferenceNo:       req.RequestId,
			FeeType:           "",
			ActualFeeAmount:   decimal.NewFromFloat(rechargeAmountFloat),
			ActualFeeCurrency: req.CardCurrency,
			Status:            "pending",
			CreatedAt:         time.Now(),
		}
		if err := c.db.Create(&record).Error; err != nil {
			log.Printf("[OpenCard] HlPay开卡pending记录写入失败: %v", err)
		} else {
			openRecordID = record.ID
			log.Printf("[OpenCard] HlPay开卡pending记录写入成功: UserID=%d, MatrixAccount=%s, ReqID=%s", userInfo.UserID, matrixAccountInfo.MatrixAccount, req.RequestId)
		}
	}

	// 使用平台管理器处理开卡请求
	result, err := c.platformManager.HandleOpenCard(ctx.Request.Context(), platformInfo.PlatformType, openCardRequest)
	if err != nil {
		fmt.Printf("[OpenCard] 开卡失败: %v\n", err)
		// 处理平台错误
		if platformErr, ok := err.(*integration.PlatformError); ok {
			fmt.Printf("[OpenCard] 平台错误详情:\n")
			fmt.Printf("  - 平台ID: %s\n", platformErr.PlatformID)
			fmt.Printf("  - 错误代码: %s\n", platformErr.Code)
			fmt.Printf("  - 错误消息: %s\n", platformErr.Message)

			// 构造PhotonPay格式的错误响应
			errorResponse := gin.H{
				"code": "400",
				"msg": gin.H{
					"CN": "开卡失败",
					"EN": "Failed to open card",
					"VN": "Mở thẻ thất bại",
				},
				"data": platformErr.Message,
			}

			// 将错误响应转换为JSON字符串以便打印
			errorResponseJSON, _ := json.Marshal(errorResponse)
			fmt.Printf("[OpenCard] 返回错误响应: %s\n", string(errorResponseJSON))

			ctx.JSON(http.StatusBadRequest, errorResponse)
		} else {
			fmt.Printf("[OpenCard] 非平台错误: %T - %v\n", err, err)
			common.Error(ctx, http.StatusInternalServerError, "open_card_failed", err)
		}
		// HlPay平台开卡失败，更新pending记录为failed
		if platformInfo.PlatformType == "hlpay" && openRecordID > 0 {
			c.db.Model(&models.HlpayCardOpenRecord{}).Where("id = ?", openRecordID).Update("status", "failed")
		}
		return
	}

	fmt.Printf("[OpenCard] 开卡成功: %+v\n", result)

	// 保存卡片信息到本地数据库
	if result.Code == "0000" {
		cardID := result.Data
		if cardID != "" {
			// 获取CardBin，优先使用bin字段，如果没有则使用cardBin字段
			cardBin := req.Bin
			if cardBin == "" {
				cardBin = req.CardBin
			}

			c.saveCardToDatabase(ctx, cardID, userInfo.UserID, platformInfo.PlatformType, req.Nickname, rechargeAmountFloat, cardBin)
			log.Printf("[OpenCard] 成功保存卡片到数据库: CardID=%s, UserID=%d, Platform=%s, Nickname=%s, RechargeAmount=%f, CardBin=%s",
				cardID, userInfo.UserID, platformInfo.PlatformType, req.Nickname, rechargeAmountFloat, cardBin)

			// HlPay平台开卡成功，更新pending记录为success并补全CardID
			if platformInfo.PlatformType == "hlpay" && openRecordID > 0 {
				c.db.Model(&models.HlpayCardOpenRecord{}).Where("id = ?", openRecordID).Updates(map[string]interface{}{
					"card_id": cardID,
					"status":  "success",
				})
				log.Printf("[OpenCard] HlPay开卡记录更新成功: CardID=%s, RecordID=%d", cardID, openRecordID)
			}
		} else {
			log.Printf("[OpenCard] 警告：卡片ID为空，跳过数据库保存")
		}
	}

	// 临时日志：记录开卡成功但跳过余额扣除
	if hasRechargeAmount && platformInfo.PlatformType == "hlpay" {
		log.Printf("[OpenCard] HlPay开卡成功，但暂时跳过余额扣除（将通过webhook回调处理）: 金额=%f, 用户ID=%d", rechargeAmountFloat, userInfo.UserID)
	} else if hasRechargeAmount && platformInfo.PlatformType == "photonpay" {
		log.Printf("[OpenCard] PhotonPay平台跳过本地余额扣除，由第三方平台处理: 金额=%f, 用户ID=%d", rechargeAmountFloat, userInfo.UserID)
	}

	// 返回统一格式的响应
	common.Success(ctx, result)
}

// BatchOpenCard 批量开卡接口
func (c *UnifiedCardController) BatchOpenCard(ctx *gin.Context) {
	// 从中间件获取平台信息
	platformInfo, exists := middleware.GetPlatformInfoFromContext(ctx)
	if !exists {
		common.Error(ctx, http.StatusUnauthorized, "platform_info_not_found", nil)
		return
	}

	// 获取矩阵账户信息
	matrixInfo, exists := ctx.Get("matrix_account_info")
	if !exists {
		common.Error(ctx, http.StatusUnauthorized, "matrix_account_not_found", nil)
		return
	}

	matrixAccountInfo, ok := matrixInfo.(*models.UserMatrixAccount)
	if !ok {
		common.Error(ctx, http.StatusInternalServerError, "matrix_account_invalid", nil)
		return
	}

	// 获取用户角色和余额信息
	userInfo, err := c.getUserRoleAndBalance(ctx)
	if err != nil {
		common.Error(ctx, err.(*errors.AppError).Code, err.Error(), nil)
		return
	}

	// 解析批量开卡请求参数
	var req service.BatchOpenCardRequest

	if err := ctx.ShouldBindJSON(&req); err != nil {
		common.Error(ctx, http.StatusBadRequest, "invalid_params", err)
		return
	}

	// 验证至少有一个BIN字段被提供
	if req.Bin == "" && req.CardBin == "" {
		common.Error(ctx, http.StatusBadRequest, "bin_required", fmt.Errorf("either 'bin' or 'cardBin' field is required"))
		return
	}

	// 验证cardholderId
	if req.CardholderId == "" || req.CardholderId == "undefined" {
		common.Error(ctx, http.StatusBadRequest, "invalid_cardholder_id", fmt.Errorf("cardholderId is required and cannot be 'undefined'"))
		return
	}

	// 设置默认超时时间为15秒
	if req.TimeoutSeconds <= 0 {
		req.TimeoutSeconds = 15
	}

	// 创建批量开卡服务
	batchCardService := service.NewBatchCardService(c.platformManager)

	// 转换用户信息格式
	userInfoForService := &service.UserRoleBalance{
		RoleID:  userInfo.RoleID,
		UserID:  userInfo.UserID,
		Balance: userInfo.Balance,
	}

	// 处理批量开卡
	result, err := batchCardService.ProcessBatchOpenCard(ctx.Request.Context(), &req, userInfoForService, matrixAccountInfo, platformInfo.PlatformType)
	if err != nil {
		common.Error(ctx, http.StatusBadRequest, "batch_open_card_failed", err)
		return
	}

	// 返回成功响应
	response := gin.H{
		"code": "0000",
		"msg": map[string]string{
			"CN": "批量开卡已开始处理",
			"EN": "Batch card opening has started",
			"VN": "Mở thẻ hàng loạt đã bắt đầu",
		},
		"data": gin.H{
			"batchId":      result.BatchID,
			"cardCount":    result.CardCount,
			"status":       result.Status,
			"successCount": result.SuccessCount,
			"failedCount":  result.FailedCount,
			"createdAt":    result.CreatedAt,
			"message":      "批量开卡正在后台处理中，请稍后查询进度",
		},
	}

	common.Success(ctx, response)
}

// GetBatchOpenCardStatus 获取批量开卡状态
func (c *UnifiedCardController) GetBatchOpenCardStatus(ctx *gin.Context) {
	// 解析请求参数
	var req struct {
		BatchId string `json:"batchId" binding:"required"`
	}

	if err := ctx.ShouldBindJSON(&req); err != nil {
		common.Error(ctx, http.StatusBadRequest, "invalid_params", err)
		return
	}

	// 创建批量开卡服务
	batchCardService := service.NewBatchCardService(c.platformManager)

	// 获取批量开卡状态
	result, err := batchCardService.GetBatchOpenCardStatus(req.BatchId)
	if err != nil {
		common.Error(ctx, http.StatusNotFound, "batch_record_not_found", err)
		return
	}

	// 构造响应
	response := gin.H{
		"code": "0000",
		"msg": map[string]string{
			"CN": "获取批量开卡状态成功",
			"EN": "Get batch card opening status successfully",
			"VN": "Lấy trạng thái mở thẻ hàng loạt thành công",
		},
		"data": gin.H{
			"batchId":      result.BatchID,
			"status":       result.Status,
			"cardCount":    result.CardCount,
			"successCount": result.SuccessCount,
			"failedCount":  result.FailedCount,
			"createdAt":    result.CreatedAt,
			"completedAt":  result.CompletedAt,
		},
	}

	common.Success(ctx, response)
}
